package net.println.kotlin.chapter8

import net.println.kotlin.chapter4.annotations.AnotherAnno
import net.println.kotlin.chapter4.annotations.Poko

@Poko
data class Person(@AnotherAnno val name: String, val age: Int)

class DefaultConstructor()
//扩展方法
fun Person.sayHello() {
    println("Hello")
}
//包级函数
fun sayHello() {
    println("Hello")
}

fun main(args: Array<String>) {
    val clazz = Person::class.java
    val person = Person("cdcdcd",18)
    val clazz2 = person.javaClass
    val clazz3 = person::class.java

    val defaultConstructor = DefaultConstructor::class.java.newInstance()
    val aaa = clazz2.newInstance()
    val person2 = clazz2.getConstructor(String::class.java,Int::class.java).newInstance("cdcdcd",19)
    val name = clazz2.getDeclaredField("name").apply { isAccessible = true }.set(person2,"Andy")
    val name2 = clazz2.getDeclaredMethod("getName").invoke(person2)
    val person3 = clazz2.getDeclaredMethod("copy",String::class.java,Int::class.java).invoke(person2,person2.name,person2.age)
    println(person3)

    //反射扩展方法
    Class.forName("net.println.kotlin.chapter8.JavaReflectionsKt")
            .getDeclaredMethod("sayHello",Person::class.java)
            .invoke(null,person2)
    //反射包级函数
    Class.forName("net.println.kotlin.chapter8.JavaReflectionsKt")
            .getDeclaredMethod("sayHello")
            .invoke(null)

    //访问注解类
    clazz.getAnnotation(Poko::class.java).let(::println)
    //访问注解字段
    clazz.getDeclaredField("name").apply { isAccessible = true }.annotations.forEach(::println)
}